"""
会员（用户）模块
"""
import os
from fastapi import APIRouter, Depends, Query, Path, Header, Body, HTTPException, UploadFile, File
from sqlalchemy.orm import Session
from typing import Optional
from dbs.database import get_db
from dbs.schemas import UserInfo, RegistUser, CreateUserInfo
from dbs.user_crud import get_users, read_user, active_user, get_user_by_id, \
    remove_user_by_id, get_user, update_user, create_user, update_user_avater
from dbs.cache import has_token, remove_token, get_user_id
from errors import JPGError, FileMaxSizeError
from settings import STATIC_DIR

user_router = APIRouter()


@user_router.get('/users')
async def all_users(db: Session = Depends(get_db)):
    return get_users(db)


@user_router.get('/login')
async def login(
        name: str = Query(..., max_length=10, regex='^[a-zA-Z]+$'),
        pwd: str = Query(..., min_length=3, max_length=20),
        db: Session = Depends(get_db)
):
    return read_user(name, pwd, db)


@user_router.get('/active/{id}')
async def active(
        id: int = Path(..., ge=1),
        db: Session = Depends(get_db)
):
    user = active_user(db, id=id)
    return {"msg": "账户已经激活", "user": user}


@user_router.put('/user', description='更新用户信息', name='修改用户信息')
async def update_user(
        token: Optional[str] = Header(..., max_length=32, min_length=32, title="请求头Token"),
        user: UserInfo = Body(...),
        db: Session = Depends(get_db)
):
    # 1 验证token是否有效
    # 2 有效时获取对应ID
    # 3 获取 User的对应数据
    # 4 更新对应数据
    if not has_token(token):
        raise HTTPException(status_code=403, detail="无效的Token")
    user_id = get_user_id(token)
    updated_user = update_user(db, user_id, user)
    return {"user": updated_user}


@user_router.post('/register_user', response_model=CreateUserInfo)
async def register_user(
        user: RegistUser = Body(...),
        friend_code: Optional[str] = Query(None, title="邀请码"),
        db: Session = Depends(get_db)
):
    if get_user(db, user.username):
        raise HTTPException(status_code=400, detail="Username already registered")
    new_user = create_user(db=db, user=user)
    return new_user


@user_router.delete('/remove_user/{user_id}')
async def remove_user(db: Session = Depends(get_db), user_id: int = Path(..., ge=1)):
    if not get_user_by_id(db, user_id):
        raise HTTPException(status_code=403, detail="账户不存在")
    remove_user_by_id(db=db, id=user_id)
    return {"msg": "账号已经删除"}


@user_router.get('/logout')
async def logout(token: Optional[str] = Header(...)):
    remove_token(token)
    return {'msg': '用户已退出！'}


# 上传用户头像接口，要求请求头中包含Token标识用户（用户登录后的操作）
@user_router.post('/avater')
async def upload_user_avater(
        db: Session = Depends(get_db),
        token: Optional[str] = Header(...),
        image: UploadFile = File(...)
):
    # 1 验证图片大小和类型（jpg或png）
    if image.content_type != 'image/jpeg':
        raise JPGError()
    content = await image.read()
    if len(content) > 2 * 1024 * 1024:
        # raise HTTPException(status_code=422, detail="图片大小不能超过2M", headers={"X-Error":"file type error!"})
        raise FileMaxSizeError()

    # 2 保存文件
    user_id = get_user_id(token=token)
    filename = os.path.join(STATIC_DIR, f'avaters/{user_id}.jpg')
    with open(filename, 'wb') as fp:  # 读取的是字节数据，所以用wb
        fp.write(content)

    # 3 更新数据库
    user = update_user_avater(db=db, user_id=user_id, avater_filename=f'avaters/{user_id}.jpg')

    return {
        "msg": '用户头像上传成功！',
        "path": f'avaters/{user_id}.jpg',
        "user": user
    }


@user_router.patch('/renew_password')
async def update_user_password():
    pass
